/**
 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

<%= $HEADER %>

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define OPCODE_LIST(DEF) \
% IR::instructions.each do |inst|
% flags = inst.flags.empty? ? ['none'] : inst.flags
% flags << 'pseudo_dst' if !inst.operands.empty? && inst.operands.first.has('pseudo')
% flags << 'no_dst' if inst.operands.empty? || !inst.operands.first.is_dst?
    DEF( <%= inst.opcode.ljust(20) %>, <%= inst.base.ljust(20) %>, <%= flags.map{|x| x.upcase }.join('|') %> ) \
% end

namespace ark::compiler {
% IR::instructions.map { |x| x.base }.select { |base| not base.include? "<" }.map.uniq.each do |base|
class <%= base %>;
% end
}  // namespace ark::compiler

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define FLAGS_LIST(DEF) \
% IR::flags.each_pair do |flag, v|
    DEF(<%= flag.upcase %>) \
% end

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define INST_CAST_TO_DECL() \
% IR::instructions.each do |inst|
          <%= inst.base.ljust(20) %> *CastTo<%= inst.opcode.ljust(20) %>(); \
    const <%= inst.base.ljust(20) %> *CastTo<%= inst.opcode.ljust(20) %>() const; \
% end

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define INST_CAST_TO_DEF() \
% IR::instructions.each do |inst|
inline       <%= inst.base.ljust(20) %> *Inst::CastTo<%= inst.opcode.ljust(20) %>()       { ASSERT(GetOpcode() == Opcode::<%= inst.opcode.ljust(20) %>); return static_cast<      <%= inst.base %> *>(this); } \
inline const <%= inst.base.ljust(20) %> *Inst::CastTo<%= inst.opcode.ljust(20) %>() const { ASSERT(GetOpcode() == Opcode::<%= inst.opcode.ljust(20) %>); return static_cast<const <%= inst.base %> *>(this); } \
% end


#ifndef NDEBUG
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define INST_MODES_LIST \
% IR::instructions.each do |inst|
    <%= inst.modes.map{|x| x.upcase }.join('|') %>, \
% end

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define MODES_LIST(DEF) \
% IR::modes.each_pair do |mode, v|
    DEF(<%= mode.upcase %>) \
% end

#endif
